#include "DiskSpace.h"

#include <time.h>
#include <list>
#include <vector>

#ifndef WIN32
#include <sys/statfs.h>
#include <dirent.h>
/*#include <sys/vfs.h> or <sys/statfs.h> */
#include <sys/vfs.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#else
#include <io.h>
#include <direct.h>
#include <Windows.h>
#endif

#include "pfunc_print.h"

int pyfree::getDiskFreeSpace(char _DiskStr, int &_totalSize, int &_freeSize)
{
#ifdef WIN32
	BOOL fResult;
	unsigned _int64 i64FreeBytesToCaller;
	unsigned _int64 i64TotalBytes;
	unsigned _int64 i64FreeBytes;
	char dir[4] = { _DiskStr, ':', '\\' };
	fResult = GetDiskFreeSpaceEx(
		dir,
		(PULARGE_INTEGER)&i64FreeBytesToCaller,
		(PULARGE_INTEGER)&i64TotalBytes,
		(PULARGE_INTEGER)&i64FreeBytes);
	//GetDiskFreeSpaceEx function,get the disk space status,return BOOL type    
	if (fResult)//jude the disk is in work status by the return value   
	{
		_totalSize = static_cast<int>(static_cast<float>(i64TotalBytes) / 1024 / 1024);
		_freeSize = static_cast<int>(static_cast<float>(i64FreeBytesToCaller) / 1024 / 1024);

		//std::cout << " totalspace:" << _totalSize << " MB" << std::endl;//disk total size    
		//std::cout << " freespace:" << _freeSize << " MB" << std::endl;//disk free space sze   
	}
#endif // WIN32
#ifdef __linux__
	//printf("DiskFlag(%c)\n", _DiskStr);
	struct statfs diskInfo;
	statfs("/", &diskInfo);
	unsigned long long totalBlocks = diskInfo.f_bsize;
	unsigned long long totalSize = totalBlocks * diskInfo.f_blocks;
	_totalSize = static_cast<int>(totalSize >> 20);
	//printf("TOTAL_SIZE == %d MB\n", _totalSize);

	unsigned long long freeDisk = diskInfo.f_bfree*totalBlocks;
	_freeSize = static_cast<int>(freeDisk >> 20);
	//printf("DISK_FREE == %d MB\n", _freeSize);
#endif
	return 1;
}

//delete old file which is older taday for the file modify time
void pyfree::moveOldFile(std::string _dir, const std::string &extname, int dayForLimit_)
{
	try{
#ifdef WIN32
	_finddata_t fileInfo;
	intptr_t hFile;
	std::string filter = _dir;
	if (filter[filter.size() - 1] != '//' || filter[filter.size() - 1] != '\\') {
		filter.push_back('\\');
	}
	filter += "*.";
	filter += extname;

	//time_t file_time_ = time(NULL);
	time_t file_time_ = (time_t)getCurDayZeroClockTime(dayForLimit_*86400);
	//get
	hFile = _findfirst(filter.c_str(), &fileInfo);
	if (hFile == -1) {
		return;
	}
	std::string delOldFile = "";
	//find the oldest file by modify time 
	do {
		if (extname.empty())//no ext name, that is dir
		{
			if ((fileInfo.attrib & _A_SUBDIR)) {
				if (0 == strcmp(fileInfo.name, ".") || 0 == strcmp(fileInfo.name, ".."))
				{
					continue;
				}
			}
		}
		//if(fileInfo.time_write<_time)//modify time
		if (fileInfo.time_create<file_time_)//create time
		{
			file_time_ = fileInfo.time_create;
			delOldFile = _dir + "//" + (std::string(fileInfo.name));
		}
	} while (_findnext(hFile, &fileInfo) == 0);
	_findclose(hFile);
#endif

#ifdef linux
	//printf("moveOldFile(*.%s) 1 from(%s) \n",extname.c_str(),_dir.c_str());
	std::string curdir = _dir;
	if (curdir[curdir.size() - 1] != '/') {
		curdir.push_back('/');
	}
	DIR *dfd;
	if ((dfd = opendir(curdir.c_str())) == NULL)
	{
		Print_WARN("open %s error with msg is: %s\n", curdir.c_str(), strerror(errno));
		return;
	}
	struct dirent    *dp;
	//time_t file_time_ = time(NULL);
	time_t file_time_ = (time_t)getCurDayZeroClockTime(dayForLimit_ * 86400);
	std::string delOldFile = "";
	while ((dp = readdir(dfd)) != NULL)
	{
		if (extname.empty())//no ext name, that is dir
		{
			if (dp->d_type == DT_DIR) {
				if (0 == strcmp(dp->d_name, ".") || 0 == strcmp(dp->d_name, ".."))
				{
					continue;
				}
			}
		}
		else {
			if (NULL == strstr(dp->d_name, extname.c_str()))
			{
				continue;
			}
		}
		std::string _path = _dir + "/";
		_path += dp->d_name;
		struct stat el;
		stat(_path.c_str(), &el);
		if (el.st_mtime<file_time_) {
			file_time_ = el.st_mtime;
			delOldFile = _path;
		}
	}
	if (NULL != dp) {
		delete dp;
		dp = NULL;
	}
	if (NULL != dfd) {
		closedir(dfd);
		dfd = NULL;
	}
#endif
	if (!delOldFile.empty())
	{
		//printf("get old file: %s \n", delOldFile.c_str());
		
		int ret = remove(delOldFile.c_str());
		if (0 != ret) {
			Print_WARN("can't remove %s \n", delOldFile.c_str());
		}else{
			Print_NOTICE("success remove %s \n", delOldFile.c_str());
		}
		
	}
	}catch(...){
		Print_TRACE("moveOldFile(*.%s) from(%s) exception error\n"
			,extname.c_str(),_dir.c_str());
	}
}

int pyfree::getCurDayZeroClockTime(int deviation)
{
	int ZeroClockTime_ = 0;
	time_t cur_time_ = time(NULL);
	struct tm _tt;
#ifdef WIN32
	localtime_s(&_tt, &cur_time_);
#else
	localtime_r(&cur_time_,&_tt);
#endif
	//当日凌晨时刻
	_tt.tm_hour = 0;
	_tt.tm_min = 0;
	_tt.tm_sec = 0;
	ZeroClockTime_ = static_cast<int>(mktime(&_tt));
	ZeroClockTime_ -= deviation;//偏移时间
	return ZeroClockTime_;
}
